import type Table from './table.vue'
import type { ExtractPropTypes } from 'vue'
import type { ElTableColumn } from 'element-plus'
import { buildProps, definePropType, isArray } from '@/utils'

export interface TableColumn<T extends string = string> {
  key: T
  label?: string
  slot?: boolean
  width?: number
  fixed?: 'left' | 'right'
  attrs?: Partial<ExtractPropTypes<typeof ElTableColumn>> & Record<string, any>
  customRender?: (value: any, row: Record<string, any>, index: number) => string
}

export interface TablePaginationOptions {
  currentPage: number
  pageSize: number
  pageSizes: number[]
}

type TablePropsHttp = (params: any) => Promise<Service.ResultPagination<any[]>>

export const tableProps = buildProps({
  // 显示序号列
  series: {
    type: Boolean,
    default: true
  },
  seriesAttrs: {
    type: Object,
    default: () => ({})
  },
  columns: {
    type: definePropType<TableColumn[]>(Array),
    required: true
  },
  selectKeys: {
    type: Array
  },
  // 切换页码/http调用/data更新
  // 不会根据table数据，过滤selectKeys
  selectKeysKeep: {
    type: Boolean,
    default: true
  },
  // 行数据的 Key
  rowKey: {
    type: definePropType<string | ((row: Record<string, any>) => any)>([
      String,
      Function
    ]),
    default: 'id'
  },
  paginationConfig: {
    type: definePropType<false | TablePaginationOptions>([Boolean, Object]),
    default: (): TablePaginationOptions => ({
      currentPage: 1,
      pageSize: 15,
      pageSizes: [15, 20, 30]
    })
  },
  loading: Boolean,
  // 使用 hooks/usePagination 进行内部分页
  // http和data同时设置，使用http
  data: {
    type: Array,
    default: () => []
  },
  // http 不会立即执行、params发生变化、isReload = true 调用http
  httpLazy: Boolean,
  // 重新请求http
  isReload: Boolean,
  http: {
    type: definePropType<TablePropsHttp>(Function)
  },
  params: {
    type: Object,
    default: () => ({})
  },
  // 禁用多选框
  setCheck: {
    type: definePropType<(row: any, index: number) => boolean>(Function),
    default: () => true
  },
  /**
   * @deprecated
   * 弃用属性保留最低支持
   *
   * 使用 auto-fit-height 来根据自适应高度
   *
   * 设置table高度
   */
  setTableHeight: {
    type: Boolean,
    default: false
  },

  /**
   * 保留对 setTableHeight 的最低支持默认是false
   */
  autoFitHeight: {
    type: Boolean,
    default: false
  },

  /**
   * 高度 无默认值
   */
  height: {
    type: definePropType<string | number>([Number, String])
  },

  // 重新请求http是否保留勾选数据
  reserveSelection: {
    type: Boolean,
    default: false
  }
} as const)

export const tableEmits = {
  'update:isReload': (val: false) => val === false,
  'update:selectKeys': (val: any[]) => isArray(val),
  getData: (val: any) => val
}

export type TableProps = ExtractPropTypes<typeof tableProps>
export type TableEmits = typeof tableEmits

export type TableInstance = InstanceType<typeof Table>
